package org.dromara.business.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import jakarta.annotation.Resource;
import lombok.RequiredArgsConstructor;
import org.dromara.business.constant.BusinessConstants;
import org.dromara.business.domain.Coupon;
import org.dromara.business.domain.Goods;
import org.dromara.business.domain.GoodsOrder;
import org.dromara.business.domain.ShoppingCart;
import org.dromara.business.domain.bo.GoodsOrderBo;
import org.dromara.business.domain.vo.BusinessConfigVo;
import org.dromara.business.domain.vo.GoodsOrderVo;
import org.dromara.business.domain.vo.GoodsVo;
import org.dromara.business.mapper.GoodsOrderMapper;
import org.dromara.business.service.*;
import org.dromara.business.util.WxSubscribeUtil;
import org.dromara.common.core.exception.ServiceException;
import org.dromara.common.core.service.TopUpCoreService;
import org.dromara.common.core.utils.DateUtils;
import org.dromara.common.core.utils.MapstructUtils;
import org.dromara.common.core.utils.SpringUtils;
import org.dromara.common.core.utils.StreamUtils;
import org.dromara.common.mybatis.core.page.PageQuery;
import org.dromara.common.mybatis.core.page.TableDataInfo;
import org.dromara.common.satoken.utils.LoginHelper;
import org.dromara.system.domain.SysUser;
import org.dromara.system.domain.vo.SysUserVo;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.*;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;

/**
 * 订单Service业务层处理
 *
 * @author Lion Li
 * @date 2025-06-13
 */
@RequiredArgsConstructor
@Service
public class GoodsOrderServiceImpl extends ServiceImpl<GoodsOrderMapper, GoodsOrder> implements GoodsOrderService {

    private final GoodsOrderMapper baseMapper;
    private final GoodsService goodsService;
    private final UserFlowingService flowingService;
    private final ShoppingCartService cartService;
    private final UserService userService;
    private final BusinessConfigService configService;
    private final ScheduledExecutorService scheduledExecutorService;
    private final CouponService couponService;
    @Resource
    @Lazy
    private TopUpCoreService topUpCoreService;

    /**
     * 查询订单
     */
    @Override
    public GoodsOrderVo queryById(Long goodsOrderId) {
        GoodsOrderVo goodsOrderVo = baseMapper.selectVoById(goodsOrderId);
        SysUser user = userService.getById(LoginHelper.getUserId());
        if (ObjectUtil.equal(user.getIsWaiter(), "1")) {
            goodsOrderVo.setFee(goodsOrderVo.getPrice().multiply(user.getReward()).setScale(2, RoundingMode.HALF_UP));
        }
        return goodsOrderVo;
    }

    /**
     * 查询订单列表
     */
    @Override
    public TableDataInfo<GoodsOrderVo> queryPageList(GoodsOrderBo bo, PageQuery pageQuery) {
        LambdaQueryWrapper<GoodsOrder> lqw = buildQueryWrapper(bo);
        Page<GoodsOrderVo> result = baseMapper.selectVoPage(pageQuery.build(), lqw);
        return TableDataInfo.build(result);
    }

    /**
     * 查询订单列表
     */
    @Override
    public List<GoodsOrderVo> queryList(GoodsOrderBo bo) {
        LambdaQueryWrapper<GoodsOrder> lqw = buildQueryWrapper(bo);
        return baseMapper.selectVoList(lqw);
    }

    private LambdaQueryWrapper<GoodsOrder> buildQueryWrapper(GoodsOrderBo bo) {
        Map<String, Object> params = bo.getParams();
        LambdaQueryWrapper<GoodsOrder> lqw = Wrappers.lambdaQuery();
        lqw.eq(bo.getGoodsOrderId() != null, GoodsOrder::getGoodsOrderId, bo.getGoodsOrderId());
        lqw.eq(bo.getGoodsId() != null, GoodsOrder::getGoodsId, bo.getGoodsId());
        lqw.like(StrUtil.isNotBlank(bo.getName()), GoodsOrder::getName, bo.getName());
        lqw.eq(StrUtil.isNotBlank(bo.getUrl()), GoodsOrder::getUrl, bo.getUrl());
        lqw.eq(bo.getPrice() != null, GoodsOrder::getPrice, bo.getPrice());
        lqw.eq(StrUtil.isNotBlank(bo.getInfo()), GoodsOrder::getInfo, bo.getInfo());
        lqw.eq(StrUtil.isNotBlank(bo.getOneType()), GoodsOrder::getOneType, bo.getOneType());
        lqw.eq(StrUtil.isNotBlank(bo.getType()), GoodsOrder::getType, bo.getType());
        lqw.eq(StrUtil.isNotBlank(bo.getStatus()), GoodsOrder::getStatus, bo.getStatus());
        lqw.eq(StrUtil.isNotBlank(bo.getPhone()), GoodsOrder::getPhone, bo.getPhone());
        lqw.eq(StrUtil.isNotBlank(bo.getGameIdNo()), GoodsOrder::getGameIdNo, bo.getGameIdNo());
        lqw.eq(StrUtil.isNotBlank(bo.getGameAreaType()), GoodsOrder::getGameAreaType, bo.getGameAreaType());
        lqw.eq(bo.getWaiterId() != null, GoodsOrder::getWaiterId, bo.getWaiterId());
        lqw.eq(LoginHelper.isUser() && ObjectUtil.notEqual(bo.getIsWaiter(), 1), GoodsOrder::getCreateBy, LoginHelper.getUserId());
        lqw.eq(LoginHelper.isUser() && ObjectUtil.equal(bo.getIsWaiter(), 1), GoodsOrder::getWaiterId, LoginHelper.getUserId());
        lqw.ne(GoodsOrder::getStatus, "1");
        lqw.orderByDesc(GoodsOrder::getCreateTime);
        return lqw;
    }

    /**
     * 新增订单
     */
    @Override
    public Boolean insertByBo(GoodsOrderBo bo) {
        GoodsOrder add = MapstructUtils.convert(bo, GoodsOrder.class);
        validEntityBeforeSave(add);
        boolean flag = baseMapper.insert(add) > 0;
        if (flag) {
            bo.setGoodsOrderId(add.getGoodsOrderId());
        }
        return flag;
    }

    /**
     * 修改订单
     */
    @Override
    public Boolean updateByBo(GoodsOrderBo bo) {
        GoodsOrder update = MapstructUtils.convert(bo, GoodsOrder.class);
        validEntityBeforeSave(update);
        return baseMapper.updateById(update) > 0;
    }

    /**
     * 保存前的数据校验
     */
    private void validEntityBeforeSave(GoodsOrder entity) {

    }

    /**
     * 批量删除订单
     */
    @Override
    public Boolean deleteWithValidByIds(Collection<Long> ids, Boolean isValid) {
        if (isValid) {

        }
        return baseMapper.deleteBatchIds(ids) > 0;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public GoodsOrder addOrder(GoodsOrderBo bo, int delay) {
        //每打手限三单
        if (ObjectUtil.isNotNull(bo.getWaiterId())) {
            String limitNum = configService.queryValueByKey("limitNum");
            Long count = this.lambdaQuery().eq(GoodsOrder::getWaiterId, bo.getWaiterId()).in(GoodsOrder::getStatus, "3", "4").count();
            if (count >= Integer.parseInt(limitNum)) {
                throw new ServiceException("该打手单量爆满, 请尝试选择其他打手吧!");
            }
        }
        //限购
        GoodsOrder update = MapstructUtils.convert(bo, GoodsOrder.class);
        Goods goods = goodsService.getById(update.getGoodsId());
        SysUser user = userService.getById(LoginHelper.getUserId());
        if (goods.getBuyLimit() > 0) {
            Long count = this.lambdaQuery().eq(GoodsOrder::getGoodsId, update.getGoodsId())
                .in(GoodsOrder::getStatus, "2", "3", "4", "5")
                .eq(GoodsOrder::getCreateBy, LoginHelper.getUserId()).count();
            if (count >= goods.getBuyLimit()) {
                throw new ServiceException(goods.getName() + "限购" + goods.getBuyLimit() + "件, 您已购买" + count + "件");
            }
        }

        GoodsVo goodsVo = BeanUtil.toBean(goods, GoodsVo.class);
        goodsService.setPrice(List.of(goodsVo));

        update.setGoodsId(update.getGoodsId());
        update.setName(goods.getName());
        update.setUrl(goods.getUrl());
        update.setPrice(goodsVo.getVipPrice());
        //是否使用优惠券
        if (ObjectUtil.isNotNull(bo.getCouponId())) {
            Coupon coupon = couponService.getById(bo.getCouponId());
            if (ObjectUtil.isNull(coupon) || coupon.getStatus().equals("1") || coupon.getConditionAmount().compareTo(update.getPrice()) > 0) {
                throw new ServiceException("优惠券不存在!");
            }
            BigDecimal subtract = update.getPrice().subtract(coupon.getAmount());
            update.setPrice(subtract.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : subtract);
            update.setCouponPrice(coupon.getAmount());
            update.setCouponId(coupon.getCouponId());
            coupon.setStatus("1");
            couponService.updateById(coupon);
        }

        update.setInfo(goods.getInfo());
        update.setOneType(goods.getOneType());
        update.setType(goods.getType());

        update.setWaiterId(bo.getWaiterId());
        update.setStatus(ObjectUtil.isNull(bo.getWaiterId()) ? "2" : "3");
        update.setOneTypeId(goods.getOneTypeId());
        this.save(update);
        //增加销量
        goodsService.lambdaUpdate().setSql("num = num + 1").eq(Goods::getGoodsId, update.getGoodsId()).update();
        //扣除余额
        flowingService.addAmount(LoginHelper.getUserId(), update.getPrice().multiply(new BigDecimal("-1")),
            BusinessConstants.FLOWING_TYPE_PAY, update.getGoodsOrderId(), BusinessConstants.FLOWING_TYPE_AMOUNT);
        //发送通知管理员
        scheduledExecutorService.schedule(() -> {
            Map<String, String> data = new HashMap<>();
            data.put("thing1", update.getName());//商品名称
            data.put("amount5", "￥" + update.getPrice());//订单金额
            data.put("thing14", user.getNickName());//购买人
            data.put("date2", DateUtil.format(new Date(), "yyyy年MM月dd日 HH:mm"));//下单时间
            data.put("character_string4", update.getGoodsOrderId().toString());//订单编号
            String adminUserId = configService.queryOneByKey("subscribe").getRemark();
            WxSubscribeUtil.sendSubscribeMessage(userService.getById(adminUserId).getOpenid(), "LygIpCmFE69qN9q-CL4FJuHybp1ZepgFhQqSON1G_pc", "pages/index/index", data);
        }, delay, TimeUnit.SECONDS);

        //指定打手的通知打手
        if (ObjectUtil.isNotNull(bo.getWaiterId())) {
            SysUser waiter = userService.getById(bo.getWaiterId());
            scheduledExecutorService.schedule(() -> {
                Map<String, String> data = new HashMap<>();
                data.put("character_string1", update.getGoodsOrderId().toString());//工单编号
                data.put("short_thing2", user.getNickName());//客户姓名
                data.put("thing12", update.getOneType() + " " + update.getName());//客户需求
                data.put("time6", DateUtil.format(new Date(), "yyyy年MM月dd日 HH:mm"));//日期
                WxSubscribeUtil.sendSubscribeMessage(waiter.getOpenid(), "u0c4ZyS0QbdYazizcN5Bscy0IUcA_DwOVkRcmw861sc", "pages/index/index", data);
            }, 0, TimeUnit.SECONDS);
        }
        return update;
    }

    @Override
    public GoodsOrder addOrderTopUp(GoodsOrderBo bo, Long buyFlag) {
        //每打手限三单
        if (ObjectUtil.isNotNull(bo.getWaiterId())) {
            String limitNum = configService.queryValueByKey("limitNum");
            Long count = this.lambdaQuery().eq(GoodsOrder::getWaiterId, bo.getWaiterId()).in(GoodsOrder::getStatus, "3", "4").count();
            if (count >= Integer.parseInt(limitNum)) {
                throw new ServiceException("该打手单量爆满, 请尝试选择其他打手吧!");
            }
        }
        GoodsOrder update = MapstructUtils.convert(bo, GoodsOrder.class);
        Goods goods = goodsService.getById(update.getGoodsId());

        if (goods.getBuyLimit() > 0) {
            Long count = this.lambdaQuery().eq(GoodsOrder::getGoodsId, update.getGoodsId())
                .in(GoodsOrder::getStatus, "2", "3", "4", "5")
                .eq(GoodsOrder::getCreateBy, LoginHelper.getUserId()).count();
            if (count >= goods.getBuyLimit()) {
                throw new ServiceException(goods.getName() + "限购" + goods.getBuyLimit() + "件, 您已购买" + count + "件");
            }
        }
        GoodsVo goodsVo = BeanUtil.toBean(goods, GoodsVo.class);
        goodsService.setPrice(List.of(goodsVo));

        update.setGoodsId(update.getGoodsId());
        update.setName(goods.getName());
        update.setUrl(goods.getUrl());
        update.setPrice(goodsVo.getVipPrice());
        update.setBuyFlag(buyFlag);
        //是否使用优惠券
        if (ObjectUtil.isNotNull(bo.getCouponId())) {
            Coupon coupon = couponService.getById(bo.getCouponId());
            if (ObjectUtil.isNull(coupon) || coupon.getStatus().equals("1") || coupon.getConditionAmount().compareTo(update.getPrice()) > 0) {
                throw new ServiceException("优惠券不存在!");
            }
            BigDecimal subtract = update.getPrice().subtract(coupon.getAmount());
            update.setPrice(subtract.compareTo(BigDecimal.ZERO) < 0 ? BigDecimal.ZERO : subtract);
            update.setCouponPrice(coupon.getAmount());
            update.setCouponId(coupon.getCouponId());
//            coupon.setStatus("1");
//            couponService.updateById(coupon);
        }

        update.setInfo(goods.getInfo());
        update.setOneType(goods.getOneType());
        update.setType(goods.getType());

        update.setWaiterId(bo.getWaiterId());
        update.setStatus("1");
        update.setOneTypeId(goods.getOneTypeId());
        this.save(update);
        return update;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public GoodsOrder createOrderByShoppingCartId(Long[] shoppingCartId, GoodsOrderBo bo) {
        if (ObjectUtil.isEmpty(shoppingCartId)) {
            throw new ServiceException("请选择商品");
        }
        List<ShoppingCart> shoppingCarts = cartService.listByIds(Arrays.asList(shoppingCartId));
        GoodsOrderServiceImpl aopProxy = SpringUtils.getAopProxy(this);
        for (ShoppingCart shoppingCart : shoppingCarts) {
            for (int i = 0; i < shoppingCart.getNum().intValue(); i++) {
                bo.setGoodsId(shoppingCart.getGoodsId());
                aopProxy.addOrder(bo, i);
            }
        }
        cartService.removeByIds(Arrays.asList(shoppingCartId));
        return null;
    }

    /**
     * 购物车下单微信支付
     */
    @Override
    public GoodsOrder createPayOrderByShoppingCartId(Long[] shoppingCartId, GoodsOrderBo bo) {
        long buyFlag = System.currentTimeMillis();
        if (ObjectUtil.isEmpty(shoppingCartId)) {
            throw new ServiceException("请选择商品");
        }
        List<ShoppingCart> shoppingCarts = cartService.listByIds(Arrays.asList(shoppingCartId));
        GoodsOrderServiceImpl aopProxy = SpringUtils.getAopProxy(this);
        BigDecimal totalPrice = BigDecimal.ZERO;
        for (ShoppingCart shoppingCart : shoppingCarts) {
            for (int i = 0; i < shoppingCart.getNum().intValue(); i++) {
                bo.setGoodsId(shoppingCart.getGoodsId());
                GoodsOrder goodsOrder = aopProxy.addOrderTopUp(bo, buyFlag);
                totalPrice = totalPrice.add(goodsOrder.getPrice());
            }
        }
        //返回前端下单参数
        GoodsOrder goodsOrder = new GoodsOrder();
        goodsOrder.setPrice(totalPrice);
        goodsOrder.setBuyFlag(buyFlag);
        return goodsOrder;
    }

    /**
     * 抢单大厅列表
     */
    @Override
    public IPage<GoodsOrderVo> unCheckList(PageQuery pageQuery) {
        SysUser user = userService.getById(LoginHelper.getUserId());
        //查询当前用户可抢的分类
        String typeIds = user.getTypeIds();
        if (StrUtil.isBlank(typeIds)) {
            return pageQuery.build();
        }
        IPage<GoodsOrderVo> goodsOrderVoIPage = baseMapper.selectVoPage(pageQuery.build(), new LambdaQueryWrapper<GoodsOrder>()
            .eq(GoodsOrder::getStatus, "2").in(GoodsOrder::getOneTypeId, StrUtil.split(typeIds, ","))
            .lt(GoodsOrder::getUpdateTime, DateUtil.offsetSecond(new Date(), -user.getDelayTime()))
            .orderByDesc(GoodsOrder::getCreateTime));
        if (CollectionUtil.isNotEmpty(goodsOrderVoIPage.getRecords())) {
            List<Long> userIds = StreamUtils.toList(goodsOrderVoIPage.getRecords(), GoodsOrderVo::getCreateBy);
            List<SysUser> sysUsers = userService.lambdaQuery().select(SysUser::getUserId, SysUser::getVip).in(SysUser::getUserId, userIds).list();
            List<SysUserVo> sysUserVos = BeanUtil.copyToList(sysUsers, SysUserVo.class);
            //设置vip等级
            List<BusinessConfigVo> vip = configService.queryByKey("vip");
            for (SysUserVo userVo : sysUserVos) {
                for (BusinessConfigVo configVo : vip) {
                    if (ObjectUtil.equals(configVo.getSortNo(), userVo.getVip())) {
                        userVo.setVipName(configVo.getConfigName());
                        break;
                    }
                }
            }

            for (GoodsOrderVo record : goodsOrderVoIPage.getRecords()) {
                record.setFee(record.getPrice().multiply(user.getReward()).setScale(2, RoundingMode.HALF_UP));
                record.setCreateTimeStr(DateUtils.getTimeStr(record.getCreateTime()));
                record.setUserVip(sysUserVos.stream().filter(sysUserVo -> ObjectUtil.equals(sysUserVo.getUserId(), record.getCreateBy())).map(SysUserVo::getVipName).findFirst().orElse(""));
            }
        }
        return goodsOrderVoIPage;
    }

    /**
     * 抢单
     */
    @Override
    public boolean check(Long goodsOrderId) {
        //每打手限三单
        String limitNum = configService.queryValueByKey("limitNum");
        Long count = this.lambdaQuery().eq(GoodsOrder::getWaiterId, LoginHelper.getUserId()).in(GoodsOrder::getStatus, "3", "4").count();
        if (count >= Integer.parseInt(limitNum)) {
            throw new ServiceException("最多同时服务" + limitNum + "单,请完成单子后重试吧!");
        }

        GoodsOrder order = this.getById(goodsOrderId);
        if (ObjectUtil.notEqual(order.getStatus(), "2")) {
            throw new ServiceException("单子被抢走了~.~");
        }
        boolean update = this.lambdaUpdate().set(GoodsOrder::getStatus, "3")
            .set(GoodsOrder::getWaiterId, LoginHelper.getUserId())
            .set(GoodsOrder::getUpdateTime, new Date())
            .eq(GoodsOrder::getGoodsOrderId, goodsOrderId)
            .eq(GoodsOrder::getStatus, "2").update();
        if (!update) {
            throw new ServiceException("单子被抢走了~.~");
        }
        order.setWaiterId(LoginHelper.getUserId());
        scheduledExecutorService.schedule(() -> {
            String openid = userService.getById(order.getCreateBy()).getOpenid();
            Map<String, String> data = new HashMap<>();
            data.put("thing2", order.getName());//任务标题
            data.put("character_string4", order.getGoodsOrderId().toString());//订单号
            data.put("thing9", userService.getById(order.getWaiterId()).getNickName());//接收人
            data.put("time11", DateUtil.format(new Date(), "yyyy年MM月dd日 HH:mm"));//接单时间
            data.put("thing3", "打手已接单, 请及时联系");//交单状态
            WxSubscribeUtil.sendSubscribeMessage(openid, "ILyPPtKVkWDgrHRhg8ReZnqVdnLjlABSL6jQig7X3ec", "pages/index/index", data);
        }, 0, TimeUnit.SECONDS);
        return update;
    }

    /**
     * 派单
     */
    @Override
    public boolean dispatch(Long orderId, Long userId) {
//        Order order = this.getById(orderId);
//        if (ObjectUtil.notEqual(order.getStatus(), "2")) {
//            throw new ServiceException("任务不存在");
//        }
        //每打手限三单
        String limitNum = configService.queryValueByKey("limitNum");
        Long count = this.lambdaQuery().eq(GoodsOrder::getWaiterId, userId).in(GoodsOrder::getStatus, "3", "4").count();
        if (count >= Integer.parseInt(limitNum)) {
            throw new ServiceException("该打手单量爆满, 请尝试选择其他打手吧!");
        }

        boolean update = this.lambdaUpdate().set(GoodsOrder::getStatus, "3").set(GoodsOrder::getWaiterId, userId)
            .set(GoodsOrder::getUpdateTime, new Date()).eq(GoodsOrder::getGoodsOrderId, orderId).update();
        if (!update) {
            throw new ServiceException("任务不存在");
        }
        GoodsOrder order = this.getById(orderId);
        //通知客户
        SysUser user = userService.getById(order.getCreateBy());
        scheduledExecutorService.schedule(() -> {
            String openid = user.getOpenid();
            Map<String, String> data = new HashMap<>();
            data.put("thing2", order.getName());//任务标题
            data.put("character_string4", order.getGoodsOrderId().toString());//订单号
            data.put("thing9", userService.getById(order.getWaiterId()).getNickName());//接收人
            data.put("time11", DateUtil.format(new Date(), "yyyy年MM月dd日 HH:mm"));//接单时间
            data.put("thing3", "打手已接单, 请及时联系");//交单状态
            WxSubscribeUtil.sendSubscribeMessage(openid, "ILyPPtKVkWDgrHRhg8ReZnqVdnLjlABSL6jQig7X3ec", "pages/index/index", data);
        }, 0, TimeUnit.SECONDS);
        //通知打手
        scheduledExecutorService.schedule(() -> {
            SysUser waiter = userService.getById(order.getWaiterId());
            Map<String, String> data = new HashMap<>();
            data.put("character_string1", order.getGoodsOrderId().toString());//工单编号
            data.put("short_thing2", user.getNickName());//客户姓名
            data.put("thing12", order.getOneType() + " " + order.getName());//客户需求
            data.put("time6", DateUtil.format(new Date(), "yyyy年MM月dd日 HH:mm"));//日期
            WxSubscribeUtil.sendSubscribeMessage(waiter.getOpenid(), "u0c4ZyS0QbdYazizcN5Bscy0IUcA_DwOVkRcmw861sc", "pages/index/index", data);
        }, 0, TimeUnit.SECONDS);
        return update;
    }

    /**
     * 退单
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean removeOrder(Long orderId) {
        boolean update = this.lambdaUpdate().set(GoodsOrder::getStatus, "6")
            .eq(GoodsOrder::getGoodsOrderId, orderId)
            .eq(GoodsOrder::getStatus, "2").update();
        if (!update) {
            return false;
        }
        //退还余额
        GoodsOrder order = this.getById(orderId);
        String returnWxAmount = configService.queryValueByKey("returnWxAmount");
        if (ObjectUtil.equals(returnWxAmount, "1")) {
            try {
                topUpCoreService.refundByOrderId(orderId, "goods");
            } catch (Exception e) {
                flowingService.addAmount(order.getCreateBy(), order.getPrice(), BusinessConstants.FLOWING_TYPE_REFUND, orderId, BusinessConstants.FLOWING_TYPE_AMOUNT);
            }
        } else {
            flowingService.addAmount(order.getCreateBy(), order.getPrice(), BusinessConstants.FLOWING_TYPE_REFUND, orderId, BusinessConstants.FLOWING_TYPE_AMOUNT);
        }

        //退优惠券
        if (order.getCouponId() != null) {
            couponService.lambdaUpdate().set(Coupon::getStatus, "0")
                .eq(Coupon::getStatus, "1")
                .eq(Coupon::getCouponId, order.getCouponId()).update();
        }
        return true;
    }

    /**
     * 打手完成订单
     *
     * @param orderId 订单id
     */
    @Override
    public boolean waiterEnd(Long orderId, String serverImg, String serverRemark) {
        return this.lambdaUpdate().set(GoodsOrder::getStatus, "4")
            .set(GoodsOrder::getServerImg, serverImg)
            .set(GoodsOrder::getServerRemark, serverRemark)
            .set(GoodsOrder::getUpdateTime, new Date())
            .eq(GoodsOrder::getGoodsOrderId, orderId)
            .eq(GoodsOrder::getWaiterId, LoginHelper.getUserId())
            .eq(GoodsOrder::getStatus, "3").update();
    }

    /**
     * 客户完成订单
     *
     * @param orderId 订单id
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean end(Long orderId) {
        boolean update = this.lambdaUpdate().set(GoodsOrder::getStatus, "5")
            .eq(GoodsOrder::getGoodsOrderId, orderId)
//            .eq(GoodsOrder::getCreateBy, LoginHelper.getUserId())
            .eq(GoodsOrder::getStatus, "4").update();
        if (update) {
            GoodsOrder order = this.getById(orderId);
            SysUser user = userService.getById(order.getWaiterId());
            //增加余额
            String memberIds = order.getMemberIds();
            //提成佣金
            BigDecimal price = order.getPrice();

//            BigDecimal amount = price.multiply(user.getReward()).setScale(2, RoundingMode.HALF_UP);
            if (StrUtil.isNotBlank(memberIds)) {
                List<String> memberIdList = StrUtil.split(memberIds, ",");
                //平分
                price = price.divide(new BigDecimal(memberIdList.size() + 1), 2, RoundingMode.HALF_UP);
                for (String memberId : memberIdList) {
                    SysUser member = userService.getById(memberId);
                    flowingService.addAmount(Long.parseLong(memberId), price.multiply(member.getReward()).setScale(2, RoundingMode.HALF_UP),
                        BusinessConstants.FLOWING_TYPE_REWARD, orderId, BusinessConstants.FLOWING_TYPE_AMOUNT);
                }
            }
            flowingService.addAmount(order.getWaiterId(), price.multiply(user.getReward()).setScale(2, RoundingMode.HALF_UP),
                BusinessConstants.FLOWING_TYPE_REWARD, orderId, BusinessConstants.FLOWING_TYPE_AMOUNT);

            //赠送客户积分
            String giveIntegral = configService.queryValueByKey("giveIntegral");
            flowingService.addAmount(order.getCreateBy(), price.multiply(new BigDecimal(giveIntegral)),
                BusinessConstants.FLOWING_TYPE_GOODS, orderId, BusinessConstants.FLOWING_TYPE_INTEGRAL);
        }
        return update;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean refund(Long orderId) {
        boolean update = this.lambdaUpdate().set(GoodsOrder::getStatus, "6")
            .eq(GoodsOrder::getGoodsOrderId, orderId).update();
        if (update) {
            GoodsOrder order = this.getById(orderId);
            //退还余额
            flowingService.addAmount(order.getCreateBy(), order.getPrice(), BusinessConstants.FLOWING_TYPE_REFUND,
                orderId, BusinessConstants.FLOWING_TYPE_AMOUNT);
            //退优惠券
            if (order.getCouponId() != null) {
                couponService.lambdaUpdate().set(Coupon::getStatus, "0")
                    .eq(Coupon::getStatus, "1")
                    .eq(Coupon::getCouponId, order.getCouponId()).update();
            }
        }
        return update;
    }

    @Override
    public List<String> getOrderNotice() {
        List<GoodsOrderVo> list = baseMapper.selectVoList(new LambdaQueryWrapper<GoodsOrder>()
            .orderByDesc(GoodsOrder::getCreateTime).last("limit 15"));
        List<Long> ids = StreamUtils.toList(list, GoodsOrderVo::getCreateBy);
        List<SysUser> userList = userService.listByIds(ids);
        for (GoodsOrderVo orderVo : list) {
            orderVo.setUserName(userList.stream().filter(user -> ObjectUtil.equal(user.getUserId(), orderVo.getCreateBy()))
                .map(SysUser::getNickName).findFirst().orElse("玩家"));
            orderVo.setCreateTimeStr(DateUtils.getTimeStr(orderVo.getCreateTime()));
        }
        return StreamUtils.toList(list, order -> order.getUserName() + " " + order.getCreateTimeStr() + "下单了: " + order.getOneType());
    }

    @Override
    public boolean addMember(Long orderId, List<Long> userIds) {
        for (Long userId : userIds) {
            boolean exists = userService.exists(new LambdaQueryWrapper<SysUser>().eq(SysUser::getUserId, userId));
            if (!exists) {
                throw new ServiceException(userId + "不存在");
            }
        }
        GoodsOrder goodsOrder = this.getById(orderId);
        if (StrUtil.isNotBlank(goodsOrder.getMemberIds())) {
            goodsOrder.setMemberIds(goodsOrder.getMemberIds() + "," + CollectionUtil.join(userIds, ","));
        } else {
            goodsOrder.setMemberIds(CollectionUtil.join(userIds, ","));
        }
        return this.updateById(goodsOrder);
    }

    /**
     * 将订单放回大厅订单
     *
     * @param orderId 订单id
     */
    @Override
    public boolean again(Long orderId) {
        return this.lambdaUpdate().set(GoodsOrder::getStatus, "2")
            .set(GoodsOrder::getWaiterId, null)
            .set(GoodsOrder::getMemberIds, null)
            .in(GoodsOrder::getStatus, "3", "4")
            .eq(GoodsOrder::getGoodsOrderId, orderId).update();
    }
}
